﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

using Common;

namespace WikiCsharpCommon
{
    public class WikiCsharpBugtracker
    {
        #region Bugtracker Setup Value
        private string fileExtension = ".txt";

        private string homepageTemplate = "+Bug Tracker\r\n[[buglist][Full bugs list]]\r\n[^buglist-peruser]\r\n";
        private string perUserTemplate = "+Per User\r\n[<<!--%%ADDUSER%%-->>]\r\n";
        private string userTemplate = "[[buglist-%%USERNAME%%][%%FULLNAME%%]]\r\n[<<!--%%ADDUSER%%-->>]";
        private string mainBugListTemplate = "+Bugs List - [{%%LISTNAME%%}]\r\n[^%%LISTPREFIX%%New]\r\n[^%%LISTPREFIX%%Open]\r\n[^%%LISTPREFIX%%Done]\r\n[^%%LISTPREFIX%%Close]\r\n";

        private string bugTemplate = "+++Information\r\n|BugID|State|Version|Version[<<br/>>]Corrected|Reporter|Assignee\r\n|%%BUGID%%| [<<!--%%STARTBUGSTATE%%-->>][{}][<<!--%%ENDBUGSTATE%%-->>] | [<<!--%%STARTVERSION%%-->>][{}][<<!--%%ENDVERSION%%-->>] | [<<!--%%STARTCORRECTED%%-->>][{}][<<!--%%ENDCORRECTED%%-->>] | [<<!--%%STARTREPORTER%%-->>][{}][<<!--%%ENDREPORTER%%-->>] | [<<!--%%STARTASSIGNEE%%-->>][{}][<<!--%%ENDASSIGNEE%%-->>]\r\n\r\n[<<button OnClick=\"submitOpen('%%BUGID%%')\">Open</button><button OnClick=\"submitDone('%%BUGID%%')\">Done</button><button OnClick=\"submitClose('%%BUGID%%')\">Close</button>>]\r\n\r\n+++Description\r\n|Summary|[<<!--%%STARTSUMMARY%%-->>][{}][<<!--%%ENDSUMMARY%%-->>]\r\n|Description|[<<!--%%STARTDESCRIPTION%%-->>][{}][<<!--%%ENDDESCRIPTION%%-->>]\r\n\r\n+++Notes\r\n|Date|User|Notes|Action\r\n[<<!--NEXT NOTES-->>]\r\n\r\n[<<button OnClick=\"submitAddNote('%%BUGID%%')\">Add Notes</button>>]\r\n\r\n+++Files\r\n|Date|User|Files|Action\r\n[<<!--NEXT FILES-->>]\r\n\r\n[<<button OnClick=\"submitAddFile('%%BUGID%%')\">Add Files</button>>]\r\n\r\n+++History\r\n|Date|User|Changes\r\n[<<!--NEXT CHANGES-->>]\r\n\r\n";
        private string noteTemplate = "|[{%%DATE%%}]|[{%%USERNAME%%}]|[<<!--%%START%%NOTEID%%%%-->>][{}][<<!--%%END%%NOTEID%%%%-->>]|[<<button disabled=\"true\" OnClick=\"submitEditNotes('%%BUGID%%', '%%NOTEID%%')\">Edit</button>>][<<button OnClick=\"submitDeleteNotes('%%BUGID%%', '%%NOTEID%%')\">Delete</button>>]\r\n[<<!--NEXT NOTES-->>]";
        private string fileTemplate = "|[{%%DATE%%}]|[{%%USERNAME%%}]|[<<!--%%STARTFILEID%%-->>][{}][<<!--%%ENDFILEID%%-->>]|[<<button OnClick=\"submitOpenFiles('%%BUGID%%', '%%FILEID%%')\">Open</button>>][<<button OnClick=\"submitDownloadFiles('%%BUGID%%', '%%FILEID%%')\">Download</button>>][<<button OnClick=\"submitDeleteFiles('%%BUGID%%', '%%FILEID%%')\">Delete</button>>]\r\n[<<!--NEXT FILES-->>]";
        private string changesTemplate = "|[{%%DATE%%}]|[{%%USERNAME%%}]|[{%%CHANGES%%}]\r\n[<<!--NEXT CHANGES-->>]";
        private string bugListTemplate = "+++[{%%LISTNAME%%}]\r\n|Bug ID|State|Version|Corrected|Summary|Reporter|Assignee|Action[<<!--ADDBUGINLIST-->>]";
        private string bugInListTemplate = "[<<!--ADDBUGINLIST-->>]\r\n|[%%BUGID%%]|[<<!--%%STARTBUGSTATE%%-->>][{}][<<!--%%ENDBUGSTATE%%-->>]|[<<!--%%STARTVERSION%%-->>][{}][<<!--%%ENDVERSION%%-->>]|[<<!--%%STARTCORRECTED%%-->>][{}][<<!--%%ENDCORRECTED%%-->>]|[<<!--%%STARTSUMMARY%%-->>][{}][<<!--%%ENDSUMMARY%%-->>]|[<<!--%%STARTREPORTER%%-->>][{}][<<!--%%ENDREPORTER%%-->>]|[<<!--%%STARTASSIGNEE%%-->>][{}][<<!--%%ENDASSIGNEE%%-->>]|[<<button OnClick=\"submitOpen('%%BUGID%%')\">Open</button><button OnClick=\"submitDone('%%BUGID%%')\">Done</button><button OnClick=\"submitClose('%%BUGID%%')\">Close</button>>]";

        private string[] m_bugState = { "New", "Open", "Done", "Close" };
        #endregion Bugtracker Setup Value

        #region String definition
        private string[] bugTemplateReplacement = {
                                                  @"(\[<<!--%%STARTBUGSTATE%%-->>\]\[\{)(?<value>.*)(\}\]\[<<!--%%ENDBUGSTATE%%-->>\])",
                                                  @"(\[<<!--%%STARTVERSION%%-->>\]\[\{)(?<value>.*)(\}\]\[<<!--%%ENDVERSION%%-->>\])",
                                                  @"(\[<<!--%%STARTCORRECTED%%-->>\]\[\{)(?<value>.*)(\}\]\[<<!--%%ENDCORRECTED%%-->>\])",
                                                  @"(\[<<!--%%STARTREPORTER%%-->>\]\[\{)(?<value>.*)(\}\]\[<<!--%%ENDREPORTER%%-->>\])",
                                                  @"(\[<<!--%%STARTASSIGNEE%%-->>\]\[\{)(?<value>.*)(\}\]\[<<!--%%ENDASSIGNEE%%-->>\])",
                                                  @"(\[<<!--%%STARTSUMMARY%%-->>\]\[\{)(?<value>.*)(\}\]\[<<!--%%ENDSUMMARY%%-->>\])",
                                                  @"(\[<<!--%%STARTDESCRIPTION%%-->>\]\[\{)(?<value>.*)(\}\]\[<<!--%%ENDDESCRIPTION%%-->>\])",
                                                  @"(\[<<!--%%START%%NOTEID%%%%-->>\]\[\{)(?<value>.*)(\}\]\[<<!--%%END%%NOTEID%%%%-->>\])",
                                                  @"(\[<<!--%%START%%FILEID%%%%-->>\]\[\{)(?<value>.*)(\}\]\[<<!--%%END%%FILEID%%%%-->>\])",
                                                  @"[<<!--NEXT NOTES-->>]",
                                                  @"[<<!--NEXT FILES-->>]",
                                                  @"[<<!--NEXT CHANGES-->>]",
                                                  "%%BUGID%%",
                                                  "%%DATE%%",
                                                  "%%USERNAME%%",
                                                  "%%NOTEID%%",
                                                  "%%FILEID%%",
                                                  "%%CHANGES%%",
                                                  "[<<!--ADDBUGINLIST-->>]"
                                              };

        private const string scriptTemplate = "[<<SCRIPT TYPE=\"text/javascript\">\r\n<!--\r\nfunction submitAddFile(bugID){ document.location.href = \"http://wikiname/?pagename=\" + bugID + \"&action=AddFile\";}\r\nfunction submitAddNote(bugID){ document.location.href = \"http://wikiname/?pagename=\" + bugID + \"&action=AddNote\";}\r\nfunction submitEditNote(bugID, noteID){ document.location.href = \"http://wikiname/?pagename=\" + bugID + \"&action=EditNote&noteid=\" + noteID;}\r\nfunction submitDeleteNote(bugID, noteID){ document.location.href = \"http://wikiname/?pagename=\" + bugID + \"&action=DeleteNote&noteid=\" + noteID;}\r\nfunction submitOpen(bugID){      document.location.href = \"http://wikiname/?pagename=\" + bugID + \"&action=StateOpen\";}\r\nfunction submitDone(bugID){      document.location.href = \"http://wikiname/?pagename=\" + bugID + \"&action=StateDone\";}\r\nfunction submitClose(bugID){      document.location.href = \"http://wikiname/?pagename=\" + bugID + \"&action=StateClose\";}\r\nfunction submitOpenFiles(bugID, filename){      document.location.href = \"http://wikiname/?pagename=\" + bugID + \"&action=Open&fileid=\" + filename;}\r\nfunction submitDownloadFiles(bugID, filename){      document.location.href = \"http://wikiname/?pagename=\" + bugID + \"&action=Download&fileid=\" + filename;}\r\nfunction submitDeleteFiles(bugID, filename){      document.location.href = \"http://wikiname/?pagename=\" + bugID + \"&action=Delete&fileid=\" + filename;}\r\n//-->\r\n</SCRIPT>>]\r\n";

        private string bugListPrefix = "buglist-";
        #endregion

        // File that are specific for the bug tracker
        // .bugid - number of bug
        // .users - List of username and full name
        // .current - contains the current version number (prod, test, dev)
        // .version - contains full list of version + a definition of the actual software
        // *.slock - are software lock wich are stronger that normal lock
        public bool ValidateBugTrackerFolder(string path)
        {
            return
                System.IO.File.Exists(path + "\\.bugid") &&
                System.IO.File.Exists(path + "\\.users") &&
                System.IO.File.Exists(path + "\\.current") &&
                System.IO.File.Exists(path + "\\.version");
        }

        public void InitializeBugTrackerFolder(string path)
        {
            FileHelper.WriteAllText(path + "\\.bugid", (0).ToString("0000000"));
            FileHelper.WriteAllText(path + "\\.users", "");
            FileHelper.WriteAllText(path + "\\.current", "");
            FileHelper.WriteAllText(path + "\\.version", "");

            FileHelper.WriteAllText(path + "\\homepage.txt", homepageTemplate);

            FileHelper.WriteAllText(path + "\\buglist.lock", "");
            FileHelper.WriteAllText(path + "\\buglist.txt", mainBugListTemplate.Replace("%%LISTPREFIX%%", bugListPrefix).Replace("%%LISTNAME%%", "Full"));

            FileHelper.WriteAllText(path + "\\buglist-peruser.lock", "");
            FileHelper.WriteAllText(path + "\\buglist-peruser.txt", perUserTemplate);

            foreach (var state in m_bugState)
            {
                ValidateList(path, bugListPrefix, state);
            }
        }

        public String[] GetStatusList(String path)
        {
            return m_bugState;
        }

        public int GetWIPStatusIndex(String path)
        {
            return 1;
        }

        public int GetDoneStatusIndex(String path)
        {
            return 2;
        }

        public void AddUser(string path, string username, string fullname)
        {
            using (SoftwareLock sl = new SoftwareLock(path + "\\.users"))
            {
                if (GetUserExists(path, username))
                {
                    string filecontent = FileHelper.ReadAllText(path + "\\.users");
                    FileHelper.WriteAllText(path + "\\.users", "");

                    string[] splitter = { "\r\n", "\r", "\n" };

                    string[] lines = filecontent.Split(splitter, StringSplitOptions.RemoveEmptyEntries);

                    foreach (string line in lines)
                    {
                        splitter = new string[] { "%%" };
                        string[] values = line.Split(splitter, StringSplitOptions.RemoveEmptyEntries);

                        if (values[0].ToUpper().Equals(username.ToUpper()))
                        {
                            values[1] = fullname;
                        }

                        FileHelper.AppendLine(path + "\\.users", values[0] + "%%" + values[1]);
                    }
                }
                else
                {
                    FileHelper.AppendLine(path + "\\.users", username + "%%" + fullname);
                }
            }
        }

        public bool GetUserExists(string path, string username)
        {
            string filecontent = FileHelper.ReadAllText(path + "\\.users");

            string[] splitter = { "\r\n", "\r", "\n" };

            string[] lines = filecontent.Split(splitter, StringSplitOptions.RemoveEmptyEntries);

            foreach (string line in lines)
            {
                splitter = new string[] { "%%" };
                string[] values = line.Split(splitter, StringSplitOptions.RemoveEmptyEntries);

                if (values[0].ToUpper().Equals(username.ToUpper()))
                    return true;
            }

            return false;
        }

        public string GetUserFullName(string path, string username)
        {
            if (string.IsNullOrEmpty(username))
                return username;

            foreach (var state in m_bugState)
            {
                ValidateList(path, bugListPrefix + username + "-", state);
            }

            using (SoftwareLock sl = new SoftwareLock(path + "\\.users"))
            {
                string filecontent = FileHelper.ReadAllText(path + "\\.users");

                string[] splitter = { "\r\n", "\r", "\n" };

                string[] lines = filecontent.Split(splitter, StringSplitOptions.RemoveEmptyEntries);

                foreach (string line in lines)
                {
                    splitter = new string[] { "%%" };
                    string[] values = line.Split(splitter, StringSplitOptions.RemoveEmptyEntries);

                    if (values[0].ToUpper().Equals(username.ToUpper()))
                        return values[1];
                }
            }

            return username;
        }

        public string GetUserUsername(string path, string name)
        {
            using (SoftwareLock sl = new SoftwareLock(path + "\\.users"))
            {
                string filecontent = FileHelper.ReadAllText(path + "\\.users");

                string[] splitter = { "\r\n", "\r", "\n" };

                string[] lines = filecontent.Split(splitter, StringSplitOptions.RemoveEmptyEntries);

                foreach (string line in lines)
                {
                    splitter = new string[] { "%%" };
                    string[] values = line.Split(splitter, StringSplitOptions.RemoveEmptyEntries);

                    if (values[1].ToUpper().Equals(name.ToUpper()))
                        return values[0];
                }

                return name;
            }
        }

        public String[] GetUserFullNameList(String path)
        {
            string filecontent = FileHelper.ReadAllText(path + "\\.users");

            string[] splitter = { "\r\n", "\r", "\n" };

            string[] lines = filecontent.Split(splitter, StringSplitOptions.RemoveEmptyEntries);

            List<string> list = new List<string>();

            foreach (string line in lines)
            {
                splitter = new string[] { "%%" };
                string[] values = line.Split(splitter, StringSplitOptions.RemoveEmptyEntries);

                list.Add(values[1]);
            }

            return list.ToArray();
        }

        public int GetBugCount(string path)
        {
            using (SoftwareLock sl = new SoftwareLock(path + ".bugid"))
            {
                string bugCount = FileHelper.ReadAllText(path + ".bugid");

                return Convert.ToInt32(bugCount);
            }
        }

        public string GetBugID(string path)
        {
            using (SoftwareLock sl = new SoftwareLock(path + ".bugid"))
            {
                string bugCount = FileHelper.ReadAllText(path + ".bugid");
                FileHelper.WriteAllText(path + ".bugid", (Convert.ToInt32(bugCount) + 1).ToString("0000000"));

                return bugCount;
            }
        }

        public void AddBug(string path, string version, string summary, string description)
        {
            string bugID = GetBugID(path + "\\");
            string bugContent = bugTemplate.Replace(bugTemplateReplacement[12], bugID);

            bugContent = ChangeValue(bugContent, bugTemplateReplacement[1], version);
            bugContent = ChangeValue(bugContent, bugTemplateReplacement[3], GetUserFullName(path + "\\", Environment.UserName));
            bugContent = ChangeValue(bugContent, bugTemplateReplacement[5], summary);
            bugContent = ChangeValue(bugContent, bugTemplateReplacement[6], description);

            bugContent = ChangeBugState(path, bugID, bugContent, m_bugState[0]);
            bugContent = AddChange(path, bugContent, "Bug created");

            FileHelper.WriteAllText(path + "\\" + bugID + ".lock", "");
            FileHelper.WriteAllText(path + "\\" + bugID + fileExtension, scriptTemplate + bugContent);
        }

        public dsWikiCsharpData.dtIssueDataDataTable GetBugList(string path, string state)
        {
            dsWikiCsharpData.dtIssueDataDataTable result_table = new dsWikiCsharpData.dtIssueDataDataTable();

            using (SoftwareLock sl = new SoftwareLock(path + "\\" + bugListPrefix + state + fileExtension))
            {
                ValidateList(path, bugListPrefix, state);
                String content = FileHelper.ReadAllText(path + "\\" + bugListPrefix + state + fileExtension);

                Regex reRegExp = new Regex(@"^\|\[([0-9]*)\].*\r?\n?", RegexOptions.Multiline | RegexOptions.Compiled);

                MatchCollection mc = reRegExp.Matches(content);

                foreach (Match m in mc)
                {
                    dsWikiCsharpData.dtIssueDataRow row = result_table.NewdtIssueDataRow();

                    row.IssueID = m.Groups[1].Value;
                    row.IssueAssignee = GetBugAssignee(m.Value);
                    row.IssueReporter = GetBugReporter(m.Value);
                    row.IssueStatus = GetBugState(m.Value);
                    row.IssueSummary = GetBugSummary(m.Value);

                    result_table.AdddtIssueDataRow(row);
                }
            }

            return result_table;
        }

        public void ChangeBugState(string path, string bugid, string newState)
        {
            using (SoftwareLock sl = new SoftwareLock(path + "\\" + bugid))
            {
                string content = FileHelper.ReadAllText(path + "\\" + bugid + fileExtension);
                string currentState = GetBugState(content);

                if (currentState != newState)
                {
                    content = ChangeBugState(path, bugid, content, newState);
                    content = AddChange(path, content, "Bug state", currentState, newState);

                    FileHelper.WriteAllText(path + "\\" + bugid + fileExtension, content);
                }
            }
        }

        public string ChangeBugState(string path, string bugid, string content, string newState)
        {
            string oldState = GetBugState(content);
            string version = GetBugVersion(content);
            string corrected = GetBugCorrected(content);
            string user1 = GetBugReporter(content);
            string user2 = GetBugAssignee(content);
            string username1 = GetUserUsername(path, user1);
            string username2 = GetUserUsername(path, user2);

            if (!string.IsNullOrEmpty(oldState))
            {
                RemoveBugFromList(path, bugListPrefix, bugid, oldState);
                RemoveBugFromList(path, bugListPrefix + username1 + "-", bugid, oldState);

                if (!string.IsNullOrEmpty(user2))
                    RemoveBugFromList(path, bugListPrefix + username2 + "-", bugid, oldState);
            }

            string summary = GetBugSummary(content);
            RemoveBugFromList(path, bugListPrefix, bugid, oldState);
            AddBugToList(path, bugListPrefix, bugid, newState, version, corrected, summary, user1, user2);
            AddBugToList(path, bugListPrefix + username1 + "-", bugid, newState, version, corrected, summary, user1, user2);

            if (!string.IsNullOrEmpty(user2) && !user1.Equals(user2))
                AddBugToList(path, bugListPrefix + username2 + "-", bugid, newState, version, corrected, summary, user1, user2);

            return ChangeValue(content, bugTemplateReplacement[0], newState);
        }

        public void ChangeBugAssignee(string path, string bugid, string new_assignee)
        {
            using (SoftwareLock sl = new SoftwareLock(path + "\\" + bugid))
            {
                string content = FileHelper.ReadAllText(path + "\\" + bugid + fileExtension);
                string user_assignee = GetBugAssignee(content);
                string username_assignee = GetUserUsername(path, user_assignee);

                if (username_assignee != new_assignee)
                {
                    content = ChangeBugAssignee(path, bugid, content, new_assignee);
                    content = AddChange(path, content, "Assignee", user_assignee, GetUserFullName(path, new_assignee));

                    FileHelper.WriteAllText(path + "\\" + bugid + fileExtension, content);
                }
            }
        }

        public string ChangeBugAssignee(string path, string bugid, string content, string new_assignee)
        {
            string state = GetBugState(content);
            string version = GetBugVersion(content);
            string summary = GetBugSummary(content);
            string corrected = GetBugCorrected(content);
            string user_reporter = GetBugReporter(content);
            string user_assignee = GetBugAssignee(content);
            string username_reporter = GetUserUsername(path, user_reporter);
            string username_assignee = GetUserUsername(path, user_assignee);
            string new_user_assignee = GetUserFullName(path, new_assignee);

            RemoveBugFromList(path, bugListPrefix, bugid, state);
            AddBugToList(path, bugListPrefix, bugid, state, version, corrected, summary, user_reporter, new_user_assignee);

            if (!string.IsNullOrEmpty(username_assignee))
                RemoveBugFromList(path, bugListPrefix + username_assignee + "-", bugid, state);

            if (!string.IsNullOrEmpty(new_assignee) && !username_reporter.Equals(new_assignee))
                AddBugToList(path, bugListPrefix + new_assignee + "-", bugid, state, version, corrected, summary, user_reporter, new_user_assignee);

            return ChangeValue(content, bugTemplateReplacement[4], GetUserFullName(path, new_assignee));
        }

        public void ChangeBugReporter(string path, string bugid, string new_reporter)
        {
            using (SoftwareLock sl = new SoftwareLock(path + "\\" + bugid))
            {
                string content = FileHelper.ReadAllText(path + "\\" + bugid + fileExtension);
                string user_reporter = GetBugReporter(content);
                string username_reporter = GetUserUsername(path, user_reporter);

                if (username_reporter != new_reporter)
                {
                    content = ChangeBugReporter(path, bugid, content, new_reporter);
                    content = AddChange(path, content, "Reporter", user_reporter, GetUserFullName(path, new_reporter));

                    FileHelper.WriteAllText(path + "\\" + bugid + fileExtension, content);
                }
            }
        }

        public string ChangeBugReporter(string path, string bugid, string content, string new_reporter)
        {
            string state = GetBugState(content);
            string version = GetBugVersion(content);
            string summary = GetBugSummary(content);
            string corrected = GetBugCorrected(content);
            string user_reporter = GetBugReporter(content);
            string user_assignee = GetBugAssignee(content);
            string username_reporter = GetUserUsername(path, user_reporter);
            string username_assignee = GetUserUsername(path, user_assignee);
            string new_user_reporter = GetUserFullName(path, new_reporter);

            RemoveBugFromList(path, bugListPrefix, bugid, state);
            AddBugToList(path, bugListPrefix, bugid, state, version, corrected, summary, new_user_reporter, user_assignee);

            if (!string.IsNullOrEmpty(username_reporter))
                RemoveBugFromList(path, bugListPrefix + username_reporter + "-", bugid, state);

            if (!string.IsNullOrEmpty(new_reporter) && !username_assignee.Equals(new_reporter))
                AddBugToList(path, bugListPrefix + new_reporter + "-", bugid, state, version, corrected, summary, new_user_reporter, user_assignee);

            return ChangeValue(content, bugTemplateReplacement[3], GetUserFullName(path, new_reporter));
        }

        public void AddBugToList(string path, string listfile, string bugid, string state, string version, string corrected, string summary, string reporter, string assignee)
        {
            using (SoftwareLock sl = new SoftwareLock(path + "\\" + listfile + state))
            {
                ValidateList(path, listfile, state);

                string newContent = bugInListTemplate.Replace(bugTemplateReplacement[12], bugid);
                newContent = ChangeValue(newContent, bugTemplateReplacement[0], state);
                newContent = ChangeValue(newContent, bugTemplateReplacement[1], version);
                newContent = ChangeValue(newContent, bugTemplateReplacement[2], corrected);
                newContent = ChangeValue(newContent, bugTemplateReplacement[3], reporter);
                newContent = ChangeValue(newContent, bugTemplateReplacement[4], assignee);
                newContent = ChangeValue(newContent, bugTemplateReplacement[5], summary);

                FileHelper.WriteAllText(path + "\\" + listfile + state + fileExtension,
                    FileHelper.ReadAllText(path + "\\" + listfile + state + fileExtension).Replace(bugTemplateReplacement[18], newContent));
            }
        }

        public void RemoveBugFromList(string path, string listfile, string bugid, string state)
        {
            using (SoftwareLock sl = new SoftwareLock(path + "\\" + listfile + state))
            {
                ValidateList(path, listfile, state);
                WikiCsharpTags wt = new WikiCsharpTags(@"^\|\[" + bugid + ".*\r?\n?", "");

                FileHelper.WriteAllText(path + "\\" + listfile + state + fileExtension,
                    wt.ApplyTags(FileHelper.ReadAllText(path + "\\" + listfile + state + fileExtension)));
            }
        }

        public void ValidateList(string path, string listfile, string state)
        {
            if (!System.IO.File.Exists(path + "\\" + listfile + state + fileExtension))
            {
                string mainName = listfile.Substring(0, listfile.Length - 1);

                FileHelper.WriteAllText(path + "\\" + listfile + state + ".lock", "");
                FileHelper.WriteAllText(path + "\\" + listfile + state + fileExtension, scriptTemplate + bugListTemplate.Replace("%%LISTNAME%%", state));

                if (!System.IO.File.Exists(path + "\\" + mainName + ".lock"))
                {
                    string username = mainName.Substring(mainName.IndexOf('-') + 1);
                    FileHelper.WriteAllText(path + "\\" + mainName + ".lock", "");
                    FileHelper.WriteAllText(path + "\\" + mainName + fileExtension, mainBugListTemplate.Replace("%%LISTPREFIX%%", mainName + "-").Replace("%%LISTNAME%%", GetUserFullName(path, username)));

                    using (SoftwareLock sl = new SoftwareLock(path + "\\buglist-peruser"))
                    {
                        FileHelper.WriteAllText(path + "\\buglist-peruser.txt",
                            FileHelper.ReadAllText(path + "\\buglist-peruser.txt").Replace("[<<!--%%ADDUSER%%-->>]", userTemplate).Replace("%%USERNAME%%", username).Replace("%%FULLNAME%%", GetUserFullName(path, username)));
                    }
                }
            }
        }

        public string ChangeValue(string actualContent, string regex, string newValue)
        {
            WikiCsharpTags wt = new WikiCsharpTags(regex, "${1}" + newValue + "${2}");

            return wt.ApplyTags(actualContent);
        }

        public string AddChange(string path, string content, string field, string old_value, string new_value)
        {
            if (string.IsNullOrEmpty(old_value) && string.IsNullOrEmpty(new_value))
                return content;

            if (string.IsNullOrEmpty(old_value))
                return AddChange(path, content, string.Format("Added {0} {2}", field, old_value, new_value));

            if (string.IsNullOrEmpty(new_value))
                return AddChange(path, content, string.Format("Removed {0} {1}", field, old_value, new_value));

            return AddChange(path, content, string.Format("Changed {0} from {1} to {2}", field, old_value, new_value));
        }

        public string AddChange(string path, string content, string change)
        {
            string changes = changesTemplate.Replace(bugTemplateReplacement[13], DateTime.Now.ToString("yyyy'/'MM'/'dd' 'HH':'mm':'ss"));
            changes = changes.Replace(bugTemplateReplacement[14], GetUserFullName(path + "\\", Environment.UserName));
            changes = changes.Replace(bugTemplateReplacement[17], change);

            return content.Replace(bugTemplateReplacement[11], changes);
        }

        public void AddCheckin(string path, string bugid, string note_text, string revision)
        {
            AddNote(path, bugid, note_text, "New checkin : " + revision);
        }

        public void AddNote(string path, string bugid, string note_text)
        {
            AddNote(path, bugid, note_text, "Note added");
        }

        public void AddNote(string path, string bugid, string note_text, string change)
        {
            if (!string.IsNullOrEmpty(note_text))
            {
                using (SoftwareLock sl = new SoftwareLock(path + "\\" + bugid))
                {
                    string content = FileHelper.ReadAllText(path + "\\" + bugid + fileExtension);
                    content = AddChange(path, content, change); ;

                    string note = noteTemplate.Replace(bugTemplateReplacement[13], DateTime.Now.ToString("yyyy'/'MM'/'dd' 'HH':'mm':'ss"));
                    note = note.Replace(bugTemplateReplacement[14], GetUserFullName(path + "\\", Environment.UserName));
                    note = ChangeValue(note, bugTemplateReplacement[7], note_text);

                    content = content.Replace(bugTemplateReplacement[9], note);

                    FileHelper.WriteAllText(path + "\\" + bugid + fileExtension, content);
                }
            }
        }

        public string GetBugState(string content)
        {
            Regex r = new Regex(bugTemplateReplacement[0], RegexOptions.IgnoreCase);

            return r.Match(content).Groups["value"].Value;
        }

        public void SetBugAssignee(string path, string bugid)
        {
            SetBugAssignee(path, bugid, Environment.UserName);
        }

        public void SetBugAssignee(string path, string bugid, string username)
        {
            using (SoftwareLock sl = new SoftwareLock(path + "\\" + bugid))
            {
                string content = FileHelper.ReadAllText(path + "\\" + bugid + fileExtension);
                content = SetBugAssignee(path, bugid, username, content);

                FileHelper.WriteAllText(path + "\\" + bugid + fileExtension, content);
            }
        }

        public string SetBugAssignee(string path, string bugid, string username, string content)
        {
            if (string.IsNullOrEmpty(GetBugAssignee(content)))
            {
                string temp = AddChange(path, content, "Assignee", "", GetUserFullName(path, username));
                return ChangeValue(temp, bugTemplateReplacement[4], GetUserFullName(path, username));
            }

            return content;
        }

        public string GetBugAssignee(string content)
        {
            Regex r = new Regex(bugTemplateReplacement[4], RegexOptions.IgnoreCase);

            return r.Match(content).Groups["value"].Value;
        }

        public string GetBugVersion(string content)
        {
            Regex r = new Regex(bugTemplateReplacement[1], RegexOptions.IgnoreCase);

            return r.Match(content).Groups["value"].Value;
        }

        public string GetBugCorrected(string content)
        {
            Regex r = new Regex(bugTemplateReplacement[2], RegexOptions.IgnoreCase);

            return r.Match(content).Groups["value"].Value;
        }

        public void SetBugCorrected(string path, string bugid)
        {
            using (SoftwareLock sl = new SoftwareLock(path + "\\" + bugid))
            {
                string content = FileHelper.ReadAllText(path + "\\" + bugid + fileExtension);
                content = SetBugCorrected(path, bugid, content);

                FileHelper.WriteAllText(path + "\\" + bugid + fileExtension, content);
            }
        }

        public string SetBugCorrected(string path, string bugid, string content)
        {
            if (string.IsNullOrEmpty(GetBugCorrected(content)))
            {
                string temp = AddChange(path, content, "Set bug corrected in " + GetDevVersion(path));
                return ChangeValue(temp, bugTemplateReplacement[2], GetDevVersion(path));
            }

            return content;
        }

        public void ResetBugCorrected(string path, string bugid)
        {
            using(SoftwareLock sl = new SoftwareLock(path + "\\" + bugid))
            {
                string content = FileHelper.ReadAllText(path + "\\" + bugid + fileExtension);
                content = ResetBugCorrected(path, bugid, content);

                FileHelper.WriteAllText(path + "\\" + bugid + fileExtension, content);
            }
        }

        public string ResetBugCorrected(string path, string bugid, string content)
        {
            if (!string.IsNullOrEmpty(GetBugCorrected(content)))
            {
                string temp = AddChange(path, content, "Set bug not corrected");
                return ChangeValue(temp, bugTemplateReplacement[2], "");
            }

            return content;
        }

        public string GetBugReporter(string content)
        {
            Regex r = new Regex(bugTemplateReplacement[3], RegexOptions.IgnoreCase);

            return r.Match(content).Groups["value"].Value;
        }

        public string GetBugSummary(string content)
        {
            Regex r = new Regex(bugTemplateReplacement[5], RegexOptions.IgnoreCase);

            return r.Match(content).Groups["value"].Value;
        }

        #region Version management
        public void AddVersion(string path, string version)
        {
            if (!VersionExists(path, version))
                FileHelper.AppendLine(path + "\\.version", version);
        }

        public void SetTestVersion(string path, string version)
        {
            AddVersion(path, version);
            string[] splitter = { "\r\n", "\r", "\n" };
            string[] splitter2 = { "%%" };
            string[] current = FileHelper.ReadAllText(path + "\\.current").Split(splitter, StringSplitOptions.RemoveEmptyEntries);

            string newContent = "";

            foreach (string s in current)
            {
                string[] values = s.Split(splitter2, StringSplitOptions.RemoveEmptyEntries);

                if (!values[0].Equals("Test", StringComparison.InvariantCultureIgnoreCase))
                {
                    newContent += s + "\r\n";
                }
            }

            if (!string.IsNullOrEmpty(version))
                newContent += "Test%%" + version + "\r\n";

            FileHelper.WriteAllText(path + "\\.current", newContent);
        }

        public string GetTestVersion(string path)
        {
            string[] splitter = { "\r\n", "\r", "\n" };
            string[] splitter2 = { "%%" };
            string[] current = FileHelper.ReadAllText(path + "\\.current").Split(splitter, StringSplitOptions.RemoveEmptyEntries);

            foreach (string s in current)
            {
                string[] values = s.Split(splitter2, StringSplitOptions.RemoveEmptyEntries);

                if (values[0].Equals("Test", StringComparison.InvariantCultureIgnoreCase))
                {
                    return values[1];
                }
            }

            return "";
        }

        public void SetDevVersion(string path, string version)
        {
            AddVersion(path, version);

            SetTestVersion(path, GetDevVersion(path));

            string[] splitter = { "\r\n", "\r", "\n" };
            string[] splitter2 = { "%%" };
            string[] current = FileHelper.ReadAllText(path + "\\.current").Split(splitter, StringSplitOptions.RemoveEmptyEntries);

            string newContent = "";

            foreach (string s in current)
            {
                string[] values = s.Split(splitter2, StringSplitOptions.RemoveEmptyEntries);

                if (!values[0].Equals("Dev", StringComparison.InvariantCultureIgnoreCase))
                {
                    newContent += s + "\r\n";
                }
            }

            if (!string.IsNullOrEmpty(version))
                newContent += "Dev%%" + version + "\r\n";

            FileHelper.WriteAllText(path + "\\.current", newContent);
        }

        public string GetDevVersion(string path)
        {
            string[] splitter = { "\r\n", "\r", "\n" };
            string[] splitter2 = { "%%" };
            string[] current = FileHelper.ReadAllText(path + "\\.current").Split(splitter, StringSplitOptions.RemoveEmptyEntries);

            foreach (string s in current)
            {
                string[] values = s.Split(splitter2, StringSplitOptions.RemoveEmptyEntries);

                if (values[0].Equals("Dev", StringComparison.InvariantCultureIgnoreCase))
                {
                    return values[1];
                }
            }

            return "";
        }

        public bool VersionExists(string path, string version)
        {
            string[] versions = GetVersionList(path);

            foreach (string s in versions)
            {
                if (s.Equals(version))
                    return true;
            }

            return false;
        }

        public string[] GetVersionList(string path)
        {
            string[] splitter = { "\r\n", "\r", "\n" };
            return FileHelper.ReadAllText(path + "\\.version").Split(splitter, StringSplitOptions.RemoveEmptyEntries);
        }
        #endregion
    }
}
